using System.ComponentModel.Composition;
using System.IO;
using System.Net;
using System.Text;

namespace SMSManager.SMSServices
{
	[Export]
	[PartCreationPolicy(CreationPolicy.NonShared)]
	public class WebController
	{
		private const int DefaultTimeOut = 5000;

		private readonly StringBuilder _sendData;

		private CookieContainer _cookieContainer;
		private Encoding _encoding;
		private string _referer = "";

		[ImportingConstructor]
		public WebController()
			: this(Encoding.UTF8)
		{
		}

		public WebController(Encoding encoding)
		{
			_encoding = encoding;
			_sendData = new StringBuilder();
			_cookieContainer = new CookieContainer();
		}

		public Encoding Encoding
		{
			get { return _encoding; }
			set { _encoding = value; }
		}

		public string Referer
		{
			set { _referer = value; }
		}

		public void AddSendData(string key, string value)
		{
			_sendData.Append(key + "=" + value + "&");
		}

		public void InitCookieContainer()
		{
			_cookieContainer = new CookieContainer();
		}

		public void Navigate(string url)
		{
			NavigateImp(url);
		}

		public void Navigate(string url, out string content)
		{
			Stream stream = null;
			Navigate(url, out stream);
			if (stream == null)
			{
				content = null;
				return;
			}
			using (var sr = new StreamReader(stream, _encoding))
			{
				content = sr.ReadToEnd();
			}
		}

		public void Navigate(string url, out Stream stream)
		{
			HttpWebResponse response = NavigateImp(url);
			if (response == null)
			{
				stream = null;
				return;
			}
			stream = response.GetResponseStream();
		}

		private HttpWebResponse NavigateImp(string url)
		{
			var request = (HttpWebRequest) WebRequest.Create(url);
			SetHttpWebRequestHeader(request);

			request.CookieContainer = _cookieContainer;

			if (_sendData.Length > 0)
			{
				request.Method = "POST";

				using (Stream requestStream = request.GetRequestStream())
				{
					SetSendData(requestStream);
				}
			}
			else
			{
				request.Method = "GET";
			}

			_referer = url; //set the referer.
			var result = (HttpWebResponse) request.GetResponse();

			SetEncoding(result.CharacterSet);
			return result;
		}

		private void SetEncoding(string characterSet)
		{
			if (string.IsNullOrEmpty(characterSet))
			{
				return;
			}
			_encoding = Encoding.GetEncoding(characterSet);
		}

		private void SetHttpWebRequestHeader(HttpWebRequest request)
		{
			request.Accept =
				"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1) ; .NET CLR 2.0.50727; .NET CLR 3.0.04506.590; .NET CLR 3.5.20706; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)";
			request.ContentType = "application/x-www-form-urlencoded";
			request.Timeout = DefaultTimeOut;
			request.KeepAlive = true;
			request.Referer = _referer;
		}

		private void SetSendData(Stream requestStream)
		{
			_sendData.Remove(_sendData.Length - 1, 1); //remove'&'
			byte[] bytes = _encoding.GetBytes(_sendData.ToString());
			requestStream.Write(bytes, 0, bytes.Length);
			_sendData.Clear();
		}
	}
}